/**
 *
 * Copyright (C) 2013 陕西威尔伯乐信息技术有限公司
 *
 * @className:com.wellbole.sms.client.impl.HttpPostSmsClient
 * @description: 基于HTTP POST方式的发送数据客户端
 *
 * @version:v1.0.0
 * @author:李飞
 *
 * Modification History:
 * Date         Author      Version     Description
 * -----------------------------------------------------------------
 * 2013年7月1日      李飞                       v1.0.0        create
 *
 */
package com.wellbole.sms.client.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;

import com.wellbole.sms.client.SmsClient;
import com.wellbole.sms.client.util.SignUtil;

/**
 * 基于HTTP POST方式的发送数据客户端
 * @author 李飞
 *
 */
public class HttpPostSmsClient implements SmsClient {

	/**
	 * 日志
	 */
	private static final Logger logger = LogManager.getLogger(Thread.currentThread().getStackTrace()[2].getClassName());


	/**
	 * 默认超时时间,15秒
	 */
	private static final int DEFAULT_TIMEOUT = 3*1000;

	/**
	 * 服务端地址，例如：http://localhost:8888/router
	 */
	private String serverUrl;

	/**
	 * 应用访问key（可以视为应用的访问用户名）
	 */
	private String appKey;

	/**
	 * 应用访问密码
	 */
	private String appSecret;

	/**
	 * 访问方法名称
	 */
	private String methodName = "";

	/**
	 * 版本号码
	 */
	private String version = "1.0";

	/**
	 * 默认构造函数，主要用于测试
	 */
	public HttpPostSmsClient() {
		this("http://localhost:8889/router", "00001",
				"1Aed23jjt4y8tr9trtCv1nU0F");
	}

	/**
	 * 构造函数
	 *
	 * @param serverUrl
	 *            服务器地址
	 * @param appKey
	 *            app key （应用id）
	 * @param appSecret
	 *            app secret（密码）
	 */
	public HttpPostSmsClient(String serverUrl, String appKey, String appSecret) {
		this.appKey = appKey;
		this.serverUrl = serverUrl;
		this.appSecret = appSecret;
	}

	/**
	 * 执行某个函数，
	 * @param version 版本号
	 * @param methodName 方法名
	 * @param parameters 参数列表
	 * @return
	 */
	public String execute(String version, String methodName, Map<String, String> parameters){
		parameters.put("method",methodName);
        parameters.put("appKey", appKey);
        parameters.put("v", version);
        parameters.put("format", "json");
        parameters.put("locale", "zh_CN");
        //计算签名
        String sign = this.ComputeSignStr(parameters);
        parameters.put("sign", sign);
		try {
			if(logger.isDebugEnabled()){
				logger.debug("serverUrl:" + this.serverUrl);
				logger.debug("appKey:" + this.appKey);
				logger.debug("params:" + parameters);
			}
			HttpRequest request =  HttpRequest.get(this.serverUrl)
					.connectTimeout(DEFAULT_TIMEOUT)
					.contentType(HttpRequest.CONTENT_TYPE_FORM)
					.form(parameters,HttpRequest.CHARSET_UTF8)
					;
			//request.g
			return request.body(HttpRequest.CHARSET_UTF8);

		} catch (Exception e) {
			// TODO Auto-generated catch block
			return "[ClientException]出现异常，异常信息：" + e.getMessage();
		}
	}

	/**
	 * 计算签名
	 * @param parameters 参数列表
	 * @return 计算签名
	 */
	private String ComputeSignStr(Map<String, String> parameters){
		//拼接字符串
        StringBuffer sb = new StringBuffer();

        //排序
        Set<String> keys = parameters.keySet();
        List<String> listKeys = new ArrayList<String>(keys);
        Collections.sort(listKeys);
        //Encoding encoding = new UTF8Encoding();
        //头部添加密码
        sb.append(this.appSecret);
        //循环遍历添加所有参数
        for (String key:listKeys)
        {
            //添加参数名
            sb.append(key);
            String value = parameters.get(key);
            if (value != null)
            {
                //参加参数值
                sb.append(value);
            }
        }
        //尾部添加密码
        sb.append(this.appSecret);
        //用SHA1计算哈希值
        return SignUtil.sha1Hash(sb.toString());
	}
	/**
	 * @return the serverUrl
	 */
	public final String getServerUrl() {
		return serverUrl;
	}

	/**
	 * @return the appKey
	 */
	public final String getAppKey() {
		return appKey;
	}

	/**
	 * @return the appSecret
	 */
	public final String getAppSecret() {
		return appSecret;
	}

	/**
	 * @param serverUrl
	 *            the serverUrl to set
	 */
	public final void setServerUrl(String serverUrl) {
		this.serverUrl = serverUrl;
	}

	/**
	 * @param appKey
	 *            the appKey to set
	 */
	public final void setAppKey(String appKey) {
		this.appKey = appKey;
	}

	/**
	 * @param appSecret
	 *            the appSecret to set
	 */
	public final void setAppSecret(String appSecret) {
		this.appSecret = appSecret;
	}

	/**
	 * @return the methodName
	 */
	public final String getMethodName() {
		return methodName;
	}

	/**
	 * @param methodName the methodName to set
	 */
	public final void setMethodName(String methodName) {
		this.methodName = methodName;
	}

	/**
	 * @return the version
	 */
	public final String getVersion() {
		return version;
	}

	/**
	 * @param version the version to set
	 */
	public final void setVersion(String version) {
		this.version = version;
	}
}
